#ifndef __MPI_TRACER_COMMON_H
#define __MPI_TRACER_COMMON_H

#define MT

#ifdef MT
#define MT_LOCK() {if(mt_flag) { pthread_mutex_lock(&log_mutex);}}
#define MT_UNLOCK() {if(mt_flag) { pthread_mutex_unlock(&log_mutex);}}
#else
#define MT_LOCK() {}
#define MT_UNLOCK() {}
#endif


#define END_TS_DELAY 0

#define DEFAULT_BUF_SIZE 1024
#define DEFAULT_GROUP_SIZE 4096


/* must keep same order with TRACE_TYPE_NAME */
enum TRACE_TYPE{
    type_send,
    type_recv,
    type_isend,
    type_irecv,
    type_ssend,
    type_issend,
    type_bsend,
    type_ibsend,
    type_rsend,
    type_irsend,
    type_recv_init,
    type_wait,
    type_waitall,
    type_waitany,
    type_test,
    type_testall,
    type_alltoall,
    type_alltoallv,
    type_ialltoall,
    type_ialltoallv,
    type_ineighbor_alltoallv,
    type_bcast,
    type_ibcast,
    type_reduce,
    type_ireduce,
    type_allreduce,
    type_iallreduce,
    type_barrier,
    type_ibarrier,
    type_comm_split,
    type_comm_split_type,
    type_comm_dup,
    type_comm_create,
    type_cart_create,
    type_cart_sub,
    type_graph_create,
    type_dist_graph_create_adjacent,
    type_intercomm_create,
    type_intercomm_merge,
    type_gather,
    type_gatherv,
    type_igather,
    type_igatherv,
    type_allgather,
    type_allgatherv,
    type_iallgather,
    type_iallgatherv,
    type_scatter,
    type_scatterv,
    type_iscatter,
    type_iscatterv,
    type_sendrecv,
    type_reduce_scatter,
    type_COUNT
}; 

#define MAX_TRACE_NUM 100000
#define MAX_TRACE_FN 100

typedef struct trace_log_struct{
    long id;
    int type;
    long scount;
    long sdatatype_size;
    long rcount;
    long rdatatype_size;
    int peer;
    int gpeer;
    int tag;
    double start_ts;
    double return_ts;
    double end_ts;
    void* comm;
    void* private;
} trace_log_t;

typedef struct pair_log_struct{
    int src;
    int dst;
    long count;
    long total_msg_size;
    int max_msg_size;
    int min_msg_size;
    float max_bw;
    float min_bw;
    float total_bw;
    double start_ts;
    double end_ts;
} pair_log_t;

typedef struct request_node{
    long key;
    int index;
    struct list_head node;
} request_node_t;

typedef struct group_node{
    long key;
    int index;
    int num;
    int* map;
    struct list_head node;
} group_node_t;

#endif